#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

struct Link
{
	int data;						//定义数据域
	struct Link *_next; //定义指针域，存储直接后继的节点信息
} linklist;

void DisplayNode(struct Link *head);															 	//打印节点
struct Link *AppendNode(struct Link *head, int data);								//附加节点
struct Link *InsertNode(struct Link *head, int data, int Node_id); 	//插入节点
struct Link *DeleteNode(struct Link *head, int Node_id); 						//删除节点
struct Link *EmptyNode(struct Link *head);												 	//清空节点

int main(void)
{
	unsigned int i = 0;
	unsigned int id = 0;
	char rec[10];

	printf("sizeof(struct Link) = %ld\r\n", sizeof(struct Link));
	printf("sizeof(linklist) = %ld\r\n", sizeof(linklist));

	/* 建立一个单项链表 */
	struct Link *head = NULL; //创建头指针，初始化为NULL

	//如果确定继续添加结点
	while (1)
	{
		printf("请输入对应的指令执行操作:");
		scanf("%s", rec);

		if (strstr(rec, "display") != NULL)
		{
			DisplayNode(head); //根据头指针打印链表
		}
		else if (strstr(rec, "add") != NULL)
		{
			//通过函数获得链表的地址，AppendNode函数返回的是链表的头指针,
			//可以根据头指针指向的地址来获取链表中保存的数据
			printf("输入想要增加的个数：\r\n");
			scanf("%d", &id);
			for (size_t c = 0; c < id; c++)
			{
				head = AppendNode(head, i);
				i++;
			}
			DisplayNode(head); //根据头指针打印链表
		}
		else if (strstr(rec, "insert") != NULL)
		{
			printf("请输入Node_id：\r\n");
			scanf("%d", &id);
			head = InsertNode(head, i, id);
			DisplayNode(head); //根据头指针打印链表
			i++;
		}
		else if (strstr(rec, "delete") != NULL)
		{
			printf("请输入Node_id：\r\n");
			scanf("%d", &id);
			head = DeleteNode(head, id);
			DisplayNode(head); //根据头指针打印链表
			i++;
		}
		else if (strstr(rec, "empty") != NULL) //清空链表
		{
			printf("清空链表\r\n");
			head = EmptyNode(head);
			i = 0;
		}
		else if (strstr(rec, "exit") != NULL) //退出程序
		{
			printf("退出程序\r\n");
			exit(0);
		}
		else
		{
			printf("指令输入错误\r\n");
		}

		strcpy(rec, "");
	}

	return 0;
}

//打印节点
void DisplayNode(struct Link *head)
{
	int i = 0;
	struct Link *p = head;
	while (p != NULL)
	{
		printf("%5d%5d\r\n", i, p->data);
		p = p->_next;
		i++;
	}
}

//附加节点
struct Link *AppendNode(struct Link *head, int data)
{
	struct Link *p = head, *pr = NULL;

	pr = (struct Link *)malloc(sizeof(struct Link));
	if (pr == NULL)
	{
		printf("申请内存失败！！！\r\n");
		exit(0);
	}

	if (p == NULL)
	{
		/* 这里就是说明链表还未拥有任何一个元素 */
		head = pr;
	}
	else
	{
		while (p->_next != NULL)
		{
			p = p->_next;
		}
		p->_next = pr;
	}
	pr->data = data;
	pr->_next = NULL;

	return head;
}

//插入节点
struct Link *InsertNode(struct Link *head, int data, int Node_id)
{
	bool flag = true;
	struct Link *p = head, *pr = head, *pm = NULL;

	//判断插入点是否存在
	for (size_t i = 0; i < Node_id; i++)
	{
		if (pr->_next != NULL)
		{
			pr = pr->_next;
			printf("pr->data = %d\r\n", pr->data);
		}
		else
		{
			printf("需要插入的节点不存在，请检查插入ID\r\n");
			flag = false;
			break;
		}
	}

	if (flag)
	{
		/* malloc空间出来 */
		pm = (struct Link *)malloc(sizeof(struct Link));
		if (pm != NULL)
		{
			for (size_t i = 0; i < Node_id - 1; i++)
			{
				p = p->_next;
			}
			p->_next = pm;
			pm->data = data;
			pm->_next = pr;
		}
		else
		{
			printf("申请内存失败！！！\r\n");
		}
	}

	return head;
}

//删除节点
struct Link *DeleteNode(struct Link *head, int Node_id)
{
	bool flag = true;
	struct Link *p = head, *pr = head;

	//判断删除点是否存在
	for (size_t i = 0; i < Node_id; i++)
	{
		if (pr->_next != NULL)
		{
			pr = pr->_next;
			printf("pr->data = %d\r\n", pr->data);
		}
		else
		{
			printf("需要删除的节点不存在，请检查删除ID\r\n");
			flag = false;
			break;
		}
	}

	if (flag)
	{
		for (size_t i = 0; i < Node_id-1; i++)
		{
			if (p->_next != NULL)
			{
				p = p->_next;
				printf("p->data = %d\r\n", p->data);
			}
		}

		p->_next = pr->_next;
		free(pr);
	}

	return head;
}

//清空节点
struct Link *EmptyNode(struct Link *head)
{
	struct Link *p = head,*pr = NULL;

	while (p != NULL)
	{
		pr = p;
		p = p->_next;
		free(pr);
	}

	head = NULL;
	return head;
}
